package com.sprite.utils.text;

public class GenericTokenParser {

	private final char[] openToekn;
	private final char[] closeToken;
	
	private TokenHandler handler;
	
	public GenericTokenParser(String openToken, String closeToken, TokenHandler handler){
		this.openToekn = openToken.toCharArray();
		this.closeToken = closeToken.toCharArray();
		this.handler = handler;
	}
	
	public String parse(CharSequence cs){
		if(cs == null){
			return null;
		}
		
		if(cs.length()==0){
			return "";
		}
		
		String text = null;
		if(String.class.isInstance(cs)){
			text = (String)cs;
		}else{
			text = cs.toString();
		}
		
		StringBuilder builder = new StringBuilder();
		int offset = 0;
		char[] src = text.toCharArray();
		
		while(offset< src.length){
			offset = s(src,offset, openToekn, builder);
			if(offset < src.length){
				offset += openToekn.length;
				int last = s(src,offset, closeToken, null);
				if(last < src.length){
					String pString = handler.handleToken(new String(src, offset, last - offset));
					builder.append(pString);
					offset= last+closeToken.length;
				}else{
					offset = last;
				}
			}
		}
		
		
		return builder.toString();
	}
	
	private int s(char[] src, int offset, char[] token, StringBuilder builder){
		int of = offset;
		boolean isToken = true;
		
		while(of < src.length){
			isToken = true;
			for(int i=0; i< token.length; i++){
				if(src[of+i] != token[i]){
					isToken = false;
					break;
				}
			}
			
			if(isToken){
				break;
			}
			
			if(builder != null){
				builder.append(src[of]);
			}
			
			of++;
		}
		
		return of;
	}
	
	public static void main(String[] args) {
		
		String text = "{}AAA{123}BBB{234}AAA{123}BBB{234}AAA{123}BBB{234}AAA{123}BBB{234}AAA{123}BBB{234}";

		long time = System.currentTimeMillis();
		String conts = new GenericTokenParser("{", "}", new TokenHandler() {
			
			@Override
			public String handleToken(String content) {
				// TODO Auto-generated method stub
				return "?";
			}
		}).parse(text);
		
		System.out.println(conts);
		System.out.println(System.currentTimeMillis() - time);
	}
	
}
